#include "StdAfx.h"
#include "DataReceiver.h"
#include "LogWriter.h"
#include "Observers.h"
#include "BotCore.h"

BOOL DataReceiver::StoreBitmapFile(LPCTSTR lpszFileName, HBITMAP HBM)
{
	BITMAP BM; 
	BITMAPFILEHEADER BFH; 
	LPBITMAPINFO BIP; 
	HDC DC; 
	LPBYTE Buf; 	
	DWORD ColorSize,DataSize; 
	WORD BitCount; 
	HANDLE FP; 
	DWORD dwTemp;


	GetObject(HBM, sizeof(BITMAP), (LPSTR)&BM);


	BitCount = (WORD)BM.bmPlanes * BM.bmBitsPixel;
	switch (BitCount)
	{
	case 1:
	case 4:
	case 8: 
	case 32:
		ColorSize = sizeof(RGBQUAD) * (1 << BitCount); 
	case 16:
	case 24:
		ColorSize = 0; 
	}


	DataSize = ((BM.bmWidth*BitCount+31) & ~31)/8*BM.bmHeight;

	BIP=(LPBITMAPINFO)HeapAlloc(GetProcessHeap() ,HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER)+ColorSize);

	BIP->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	BIP->bmiHeader.biWidth = BM.bmWidth;
	BIP->bmiHeader.biHeight = BM.bmHeight;
	BIP->bmiHeader.biPlanes = 1;
	BIP->bmiHeader.biBitCount = BitCount;
	BIP->bmiHeader.biCompression = BI_RGB;
	BIP->bmiHeader.biSizeImage = DataSize;
	BIP->bmiHeader.biXPelsPerMeter = 0;
	BIP->bmiHeader.biYPelsPerMeter = 0;
	if (BitCount < 16) 
		BIP->bmiHeader.biClrUsed = (1<<BitCount);
	BIP->bmiHeader.biClrImportant = 0;



	BFH.bfType = 0x4d42; 
	BFH.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ BIP->bmiHeader.biClrUsed * sizeof(RGBQUAD);
	BFH.bfReserved1 = 0;
	BFH.bfReserved2 = 0;
	BFH.bfSize = BFH.bfOffBits + DataSize; 


	Buf = new BYTE[DataSize];	

	DC = GetDC(0); 
	GetDIBits(DC, HBM, 0,(WORD)BM.bmHeight, Buf, BIP, DIB_RGB_COLORS); 
	ReleaseDC(0, DC);
	
	DWORD *Buf1 = new DWORD[DataSize/4];
	BYTE *Buf2 = new BYTE[DataSize*3/4];
	int k=0;
	for(int i=0, l=0;i<(int)DataSize/4;i++)
	{		
		Buf1[i] = RGB(Buf[l+2], Buf[l+1], Buf[l]);
		Buf2[k++] = Buf[l];
		Buf2[k++] = Buf[l+1];
		Buf2[k++] = Buf[l+2];
		l+=4;
	}


	BIP->bmiHeader.biBitCount = 24;

	TP.InitPlayerParserImage((DWORD *)Buf1, BM.bmHeight, BM.bmWidth);	
	TP.ParseIsSetMenuButtons();
	

	if(TP.m_bActive)
	{
		TP.InitStakeParserImage((DWORD *)Buf1, BM.bmHeight, BM.bmWidth);
		TP.InitStackParserImage((DWORD *)Buf1, BM.bmHeight, BM.bmWidth);
		TP.InitCardsParserImage((DWORD *)Buf1, BM.bmHeight, BM.bmWidth);
		TP.InitPotParserImage((DWORD *)Buf1, BM.bmHeight, BM.bmWidth);			
		
		TP.ParseMenuButtons();
		TP.ParseBlinds(Caption.GetBuffer());
		TP.ParseTournamentNumber(Caption.GetBuffer());
		TP.Run();
				
		if(OldPos != Pos || TP.IsSomethingHappened())
		{
			OldPos = Pos;

			ObserverManager::GetInstance().UpdateDecision(_T("Thinking...."));
			Bot.SetGameInfo(TP.m_Player, &TP.m_Table, Pos);
			Bot.SetCacheInfo(TP.m_PlayerCache, &TP.m_TableCache);
			Bot.Think();
			
			BC.Init(&TP);
			BC.ThinkNew();
			
			if(AutoPlay) 
				Bot.Play(BC.Action, BC.Stake);

			LogWriter &lw = LogWriter::GetInstance();
			TCHAR logpath[1024];
			_stprintf(logpath, _T("c:\\shots\\Tournament %d log\\"), TP.m_Table.Number);	
			lw.SetDirectory(logpath);			

			TCHAR msg[1024];
			Bot.GetMessage(msg);
			
			TCHAR blinds[1024];
			_stprintf(blinds, _T(" Blinds %d/%d"), TP.m_Table.SmallBlind, TP.m_Table.BigBlind);
			StrCat(msg, blinds);
			

			lw.WriteToFile(_T("log.html"), (TCHAR*)lpszFileName, msg);


			FP=CreateFile(lpszFileName,GENERIC_READ | GENERIC_WRITE, 0, NULL,
				CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 
			WriteFile(FP,&BFH,sizeof(BITMAPFILEHEADER),&dwTemp,NULL); 
			WriteFile(FP,BIP,sizeof(BITMAPINFOHEADER) + BIP->bmiHeader.biClrUsed * sizeof(RGBQUAD),&dwTemp,NULL); 
			WriteFile(FP,Buf2,DataSize*3/4,&dwTemp,NULL);

			CloseHandle(FP); 

			if(Window)
			{
				TCHAR buf[2000];
				Bot.GetMessage(buf);
				ObserverManager::GetInstance().UpdateTable(Window, TP.GetPlayersCount(), TP.m_Player[Pos].Stack, buf);
			}
		}
	}
	else
	{
		ObserverManager::GetInstance().UpdateDecision(_T("Waiting for move..."));
		if(Window)
		{
			ObserverManager::GetInstance().UpdateTable(Window, TP.GetPlayersCount(), TP.m_Player[Pos].Stack, _T("Waiting for move..."));
		}
	}
	
	delete [] Buf;
	delete [] Buf1;
	delete [] Buf2;


	HeapFree(GetProcessHeap() ,HEAP_ZERO_MEMORY, BIP);


	return(true);
}

void DataReceiver::ReceiveScreenShot(HBITMAP iBitmapId)
{
	static int num = 1;
	CString str;
	LogWriter &lw = LogWriter::GetInstance();
	TCHAR logpath[1024];
	TP.ParseTournamentNumber(Caption.GetBuffer());
	_stprintf(logpath, _T("c:\\shots\\Tournament %d log\\"), TP.m_Table.Number);	
	lw.SetDirectory(logpath);

	lw.GetUniqueFileName(_T("bmp"), str.GetBuffer(500));
	str.ReleaseBuffer();
	str = logpath + str;	
	
	StoreBitmapFile(str, iBitmapId);

	DeleteObject(iBitmapId);
}

void DataReceiver::ReceiveCaption(TCHAR *iCaption)
{
	Caption = iCaption;
}